<?php

include_once 'Function.php';

class Protocol
{

    private $device_imei;
    private $order;
    private $device_type;
    private $device_data;
    private $check_data;
    private $end;
    private $client_ip;
    private $client_port;

    /**
     * Protocol constructor.
     * @param $data
     * @param $clientInfo
     */
    public function __construct($data, $clientInfo)
    {
        #设备IMEI
        $this->device_imei = substr($data, 0, 16);
        #命令
        $this->order = substr($data, 16, 2);
        #设备类型
        $this->device_type = substr($data, 18, 2);
        #数据
        $this->device_data = substr($data, 20, 2);
        #校验
        $this->check_data = substr($data, 22, 2);
        #结束
        $this->end = substr($data, 24, 2);
        #客户端信息
        $this->client_ip = $clientInfo['address'];
        $this->client_port = $clientInfo['port'];
    }

    /**
     * 校验值
     * @param $str
     * @return bool
     */
    public function checkData()
    {
        $str = $this->device_imei . $this->order . $this->device_type . $this->device_data;
        $check = hexdec($this->check_data);
        $check_data = getCheckData($str);
        if ($check_data != $check) {
            return false;
        }
        return true;
    }

    /**
     * 服务端返回数据
     * @return string
     */
    public function sendData()
    {
        #回复
        $back_str = '6' . substr($this->order, 1, 1);
        $check_data = getCheckData($this->device_imei . $back_str . $this->device_type . $this->device_data);
        $back_data = base_convert($check_data, 10, 16);
        if (strlen($back_data) == 1) {
            $back_data = '0' . $back_data;
        }
        $data = $this->device_imei . $back_str . $this->device_type . $this->device_data . $back_data . $this->end;
        return $data;
    }

    /**
     * @return array
     */
    public function dataInfo()
    {
        return array(
            'imei: ' => $this->device_imei,
            'order_info' => $this->getOrderInfo(),
            'device_typpe' => $this->getDeviceType(),
            'device_data' => hexdec($this->device_data)
        );
    }

    /**
     * @return array
     */
    public function getOrderInfo()
    {
        $order = hexdec($this->order);
        $version = ($order & pow(2, 7) ? 1 : 0) . ($order & pow(2, 6) ? 1 : 0);
        $command_type = ($order & pow(2, 3) ? 1 : 0) . ($order & pow(2, 2) ? 1 : 0) . ($order & pow(2, 1) ? 1 : 0) . ($order & pow(2, 0) ? 1 : 0);
        return array(
            'vesion' => $version,
            'command_type' => $this->getCommandType($command_type)
        );
    }

    /**
     * @param $command_type
     * @return string
     */
    public function getCommandType($command_type)
    {
        $command = 'Reserve';
        switch ($command_type) {
            case '0001':
                $command = '设备心跳';
                break;
            case '0010':
                $command = '设备低电压报警';
                break;
            case '0011':
                $command = '设备报警';
                break;
            case '0100':
                $command = '设备拆卸报警';
                break;
        }
        return $command;
    }

    /**
     * @return string
     */
    public function getDeviceType()
    {
        $device_type = hexdec($this->device_type);
        $device_type = ($device_type & pow(2, 3) ? 1 : 0) . ($device_type & pow(2, 2) ? 1 : 0) . ($device_type & pow(2, 1) ? 1 : 0) . ($device_type & pow(2, 0) ? 1 : 0);
        $device_name = 'Reserve';
        switch ($device_type) {
            case '0001':
                $device_name = '烟感设备';
                break;
            case '0010':
                $device_name = '气感设备';
                break;
            case '0011':
                $device_name = '水压设备';
                break;
            case '0100':
                $device_name = '温感设备';
                break;
            case '0101':
                $device_name = '声光设备';
                break;
            case '0110':
                $device_name = '手报设备';
                break;
            case '0111':
                $device_name = '无线网关';
                break;
        }
        return $device_name;
    }
}